package app.models.order;

import app.Const;
import app.kit.TypeKit;
import bank.resp.ReconciliationItemDto;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.jfinal.plugin.activerecord.Model;
import goja.StringPool;
import goja.annotation.TableBind;
import goja.lang.Lang;
import goja.plugins.sqlinxml.SqlKit;
import goja.rapid.db.DaoKit;
import goja.tuples.Quartet;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;

import java.math.BigDecimal;
import java.util.List;

import static app.Const.DATE_SPLIT;

/**
 * <p>
 * The database rlo_check_account Model.
 * </p>
 *
 * @author sagyf yang
 * @version 1.0
 * @since JDK 1.6
 */
@TableBind(tableName = "rlo_check_account")
public class CheckAccount extends Model<CheckAccount> {

    /**
     * 银行账单
     */
    public static final int BANK_OUT   = 2;
    /**
     * 账单一致
     */
    public static final int OK_OUT     = 1;
    /**
     * 状态不正确
     */
    public static final int STASUS_OUT = 3;
    /**
     * 资金不对
     */
    public static final int AMOUNT_OUT = 4;


    /**
     * The public dao.
     */
    public static final CheckAccount dao = new CheckAccount();


    private static final long serialVersionUID = 459469046449664871L;

    public void record(List<ReconciliationItemDto> reconciliationItemDtos, DateTime checkTime) {
        String findByInnerOrderno = SqlKit.sql("checkaccount.findByInnerOrderNo");

        String orderNo;

        int outcome;
        String exp = Const.NO;
        for (ReconciliationItemDto itemDto : reconciliationItemDtos) {
            String innerOrderNo = itemDto.getInnerOrderNo();
            orderNo = itemDto.getOuterOrderNo();
            CheckAccount checkAccountRecord = findFirst(findByInnerOrderno, innerOrderNo);
            if (checkAccountRecord == null) {
                Order order = Order.dao.findByOrdernoSingle(orderNo);
                int outerOrderStatus = 0;
                BigDecimal outerOrderAmount;
                if (order == null) {
                    // 2 表示银行账单
                    outcome = BANK_OUT;
                    exp = Const.YES;
                    outerOrderAmount = BigDecimal.ZERO;
                } else {
                    // 1 表示一致账单
                    outcome = OK_OUT;
                    outerOrderStatus = TypeKit.getStatus(order);
                    if (outerOrderStatus != itemDto.getOrderStatus()) {
                        // 订单状态不一致
                        exp = Const.YES;
                        // 1 表示账单状态问题
                        outcome = STASUS_OUT;
                    }
                    outerOrderAmount = order.getBigDecimal("trade_amount");
                    if (outerOrderAmount.compareTo(itemDto.getAmount()) != 0) {
                        // 4 订单金额不一致
                        exp = Const.YES;
                        outcome = AMOUNT_OUT;
                    }
                }
                // todo 优化
                CheckAccount checkAccount = new CheckAccount();
                checkAccount.set("transdate", itemDto.getTransDate());
                checkAccount.set("reqbizdate", itemDto.getReqbizDate());
                checkAccount.set("outerorderno", itemDto.getOuterOrderNo());
                checkAccount.set("innerorderno", itemDto.getInnerOrderNo());
                checkAccount.set("orderstatus", itemDto.getOrderStatus());
                checkAccount.set("ordertype", itemDto.getOrderType());
                checkAccount.set("amount", itemDto.getAmount());
                checkAccount.set("fee", itemDto.getFee());
                checkAccount.set("currency", itemDto.getCurrency());
                checkAccount.set("check_time", checkTime);
                checkAccount.set("exp_flag", exp);
                checkAccount.set("outcome", outcome);
                checkAccount.set("outerorderstatus", outerOrderStatus);
                checkAccount.set("outerorderamount", outerOrderAmount);
                checkAccount.save();
            }
        }

    }


    public Quartet<BigDecimal, BigDecimal, BigDecimal, BigDecimal> statByOrderType(String time, String order_no, String orderType) {

        String stat_sql_tmp = SqlKit.sql("checkaccount.statByOrderType");
        StringBuilder whereSql = new StringBuilder(" WHERE 1=1 ");
        List<Object> params = Lists.newArrayList();
        if (!Strings.isNullOrEmpty(time)) {
            String time_q = StringUtils.replace(time, StringPool.SLASH, StringPool.EMPTY);
            final String[] times = time_q.split(DATE_SPLIT);
            whereSql.append(" AND rca.transdate BETWEEN ? AND ? ");
            params.add(times[0]);
            params.add(times[1]);
        }
        if(!Strings.isNullOrEmpty(order_no)){
            whereSql.append(" AND rca.outerorderno LIKE ? ");
            params.add(DaoKit.like(order_no));
        }
        if(!Strings.isNullOrEmpty(orderType)){
            whereSql.append(" AND rca.ordertype = ? ");
            params.add(orderType);
        }
        String sql = String.format(stat_sql_tmp, whereSql.toString());
        final List<CheckAccount> checkAccounts = find(sql, params.toArray());
        if (Lang.isEmpty(checkAccounts)) {
            return Quartet.with(BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
        } else {
            final List<BigDecimal> amounsts = Lists.newArrayList(BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
            for (CheckAccount checkAccount : checkAccounts) {
                int ordertype = TypeKit.getInt(checkAccount, "ordertype");
                amounsts.set(ordertype == 0 ? 0 : ordertype - 1, checkAccount.getBigDecimal(Const.FIELD_AMOUNT));

            }

            return Quartet.fromCollection(amounsts);
        }
    }
}